﻿using IOP.SgrA;
using IOP.SgrA.SilkNet.Vulkan;
using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace VkSample103
{
    public class WindowConfig : IWindowConfig<Window, VulkanGraphicsManager>
    {
        public Task Config(Window window, VulkanGraphicsManager graphics)
        {
            var windowOption = window.Option;
            var lDevice = graphics.VulkanDevice;
            var basePath = AppContext.BaseDirectory;
            var document = JsonDocument.Parse(File.OpenRead(Path.Combine(basePath, "RenderPass.json")));
            var passJson = document.RootElement;
            var swapchain = lDevice.CreateDefaultSwapChain(window)
                .CreateDefaultSwapChainImageViews();
            var dImage = lDevice.CreateDepthBufferFromJson(passJson.GetProperty("DepthBufferCreateOption").GetRawText(), 
                new Extent3D(windowOption.Width, windowOption.Height, 1));
            var pass = lDevice.CreateSwapchainRenderPassFromJson("Main", swapchain, new Format[] { dImage.Format },
                passJson.GetProperty("RenderPassCreateOption").GetRawText());
            pass.CreateSwapchainFrameBuffer(swapchain, new VulkanImageView[] { dImage }, windowOption.Height, windowOption.Width)
                .ConfigBeginInfo((option) =>
                {
                    option.RenderArea = new Rect2D { Extent = new Extent2D(windowOption.Width, windowOption.Height), Offset = new Offset2D { X = 0, Y = 0 } };
                    option.ClearValues = new ClearValue[] 
                    {
                        new ClearValue() { Color = new ClearColorValue(0.2f, 0.2f, 0.2f, 0.2f) },
                        new ClearValue() { DepthStencil = new ClearDepthStencilValue(1.0f, 0) }
                    };
                });
            var i = lDevice.CreateSemaphore(ArrangeConstant.ImageAvailableSemaphore);
            var f = lDevice.CreateSemaphore(ArrangeConstant.RenderFinishSemaphore);
            window.CreateVulkanRenderDispatcher(lDevice.WorkQueues[0], swapchain, pass, i, f);
            window.ConfigResizeCallbackHandle(RasizeHandle);
            return Task.CompletedTask;
        }

        public void Initialization()
        {
        }

        private void RasizeHandle(VulkanGlfwWindow window, uint width, uint height)
        {
            window.RenderDispatcher.RecreateRenderDispatcher(width, height);
            var manager = window.GraphicsManager;
            float aspect = (float)width / height;
            foreach (var item in manager.GetCameras())
            {
                item.SetViewport(0, 0, width, height, 0, 1);
                item.SetProjectMatrix(-aspect, 1.0f, item.Near, item.Far, item.ProjectMode);
            }
        }
    }
}
